VOLVER

Curso 2 R Programming

Datatypes

Los dos puntos se usan para declarar secuencias:

qownnotes-media-y14076

qownnotes-media-y14076

qownnotes-media-n14076

qownnotes-media-n14076

Los objetos tienen atributos accesibles por la función attribute(x), tipo, nombre, etc..

Vectores son siempre del mismo tipo, estos son los posibles tipos:

qownnotes-media-e14076

qownnotes-media-e14076

Si se mezclan tipos se hace coercion, y se le asigna el tipo más aproximado a un vector, por ejemplo si hay un entero y un carácter, se convierte todo a caracter.

Se puede hacer coercion explícita con as.

qownnotes-media-N14076

qownnotes-media-N14076

qownnotes-media-t14076

qownnotes-media-t14076

Las operaciones vectorizadas nos evitan tener que implementar bucles para operar:

qownnotes-media-U14076

qownnotes-media-U14076

Cuando operas con vector con un número simple operas cada elemento del vector por ese número:

cuando haces c(2,5,1) * 2 + 100, |o que hace realmente es : c(2,5,1) * c(2, 2, 2) + c(100, 100, 100)

De la misma manera que si operas con dos vectores de distinto tamaño sólo operaran las posiciones coincidentes

c(2,5,6) + c (1,2) = c(3,7,6)

Si combinamos un vector numérico con uno literal, si hacemos paste entre ambos vectores se hace coerción del primero, se transforma en literal y adapta su tamaño al de mayor tamaño

paste(LETTERS, 1:4, sep = “-”)

qownnotes-media-Hr8364

qownnotes-media-Hr8364

Si hacemos esto

y <- x > 4

Nos devuelve en y un vector del mismo tamñano que x con la evaluación de cada elemento de x de la expresión

y <- x[x>4]

Nos devuelve un vector con los elementos de x que cumplen la expresión.

para acceder a valores concretos del vector

y <- x[c(4,7,10)]

Hay que tener cuidado, porque nada nos impide hacer y[0] que no existe en R o y[400] que tampoco existe en el vector y nos devuelve NA

Si queremos obtener todos menos el elemento en segunda posición, podemos hacerlo con el -

y <- x[c(-2)] ó x[-c(2, 10)]

Se puede poner nombre a los elementos:

vect <- c(foo = 11, bar = 2, norf = NA)

qownnotes-media-vM8364

qownnotes-media-vM8364

se pueden poner nombres a posteriori también

names(vect2) <- c(“foo”, “bar”, “norf”)

Las listas permiten tener objetos de distinto tipo:

qownnotes-media-c14076

qownnotes-media-c14076

Una Matiz son vectores con un atributo de dimensión. Este atributo en sí mismo es un vector de enteros de longitud 2 (nº columnas y nºfilas) qownnotes-media-g14076

Si llenas una matriz con valores consecutivos irá rellenando la matriz de arriba a abajo y de izquierda a derecha por toda la matriz.

qownnotes-media-J14076

qownnotes-media-J14076

Además, un vector se puede convertir en matriz añadiendo el atributo dim()

qownnotes-media-K14076

qownnotes-media-K14076

La última manera es juntando vectores que deben ser del mismo tamaño, o bien en columnas cbind o bien en filas rbind

qownnotes-media-K14076

qownnotes-media-K14076

Se puede operar sobre las matrices de la misma manera que con los vectores, pero usando la notación correcta (la tercera):

qownnotes-media-p14076

qownnotes-media-p14076

Para poner nombre a las columnas de una matriz o dataframe, hay que crear primero un vector con todos los nombres: cnames <- c(“age”, “weight”, “bp”, “rating”, “test”)

colnames(matrix) <- cnames

y lo mismo para las filas:

patients <- c(“Bill”,“Gina”,“Kelly”,“Sean”) rownames(matrix) <- patients

my_data2 <- matrix (1:20,4,5)

qownnotes-media-no8364

qownnotes-media-no8364

Los Factores son datos categorizados, que pueden ser ordenables o no. Se puede decir que un factor es vector de enteros en el que cada entero tiene una etiqueta, de manera que podamos usar la etiqueta en lugar del número entero (ejemplo usar masculino/femenino en lugar de 1/2).

De los vectores que están factorizados se pueden sacar directamente tablas sumarizadas con el conteo de cada valor. unclass te dice qué valor entero tiene el factor.

qownnotes-media-Y14076

qownnotes-media-Y14076

Para dar un orden a los factores se utiliza el argumento levels(), aquí por ejemplo si no lo usáramos el primer nivel sería “No” por orden alfabético

qownnotes-media-z14076

qownnotes-media-z14076

Valores nulos pueden ser NA (vacío) y NaN (Not a Number). NaN es un subconjunto de NA

qownnotes-media-v14076

qownnotes-media-v14076

Para eliminar valores nulos, la función complete.cases nos da las posiciones que tienen valores no nulos:

qownnotes-media-a14076

qownnotes-media-a14076

DATA FRAMES

Se usa para guardar datos tabulares. Pueden tener tipos distintos. Ademàs tienen un atributo especial que es row.names, en este caso como no hemos especificado automáticamente son enteros.

qownnotes-media-l14076

qownnotes-media-l14076

En realidad, todos los objetos en R tienen el atributo nombre, no sólo los dataframes, vectores y matrices también.

qownnotes-media-K14076 qownnotes-media-o14076

Subconjuntos

Funcionalidad para tomar subconjuntos de datos de una estructura. A continuación se ve cómo extraer elementos de una lista, distinguiendo entre un sólo [ que nos devuelve un objeto del mismo tipo, o [[ que nos devuelve únicamente un elemento.

qownnotes-media-x14076

qownnotes-media-x14076

qownnotes-media-t14076

qownnotes-media-t14076

Tambien podemos utilizar coincidencia parcial para recoger los elementos de una estructura, en este ejemplo vemos que con sólo poner ‘a’ ya nos devuelve el elemento que comienza por esa letra

qownnotes-media-V14076

qownnotes-media-V14076

Podemos por tanto usando [ pasar el nombre de una columna de un data frame como parámetro a una función. En este ejemplo la función toma de un directorio todos los archivos csv con el nombre coincidente en el vector id, y calcula la media de la columna pasada como parámetro en pollutant, en este caso los CSV tenían 2 agentes, el sulfato y el nitrato, se podían pasar ambos:

qownnotes-media-L10040

qownnotes-media-L10040

pollutantmean <- function(directory,pollutant,id = 1:332) {

TOTAL <- data.frame()

for (i in 1:length(id)){ TEMP = read.csv(file.path(directory,paste(id[i],“.csv”,sep=“”)) ,header = TRUE) TOTAL = rbind(TOTAL,TEMP)

} mean(TOTAL[,pollutant],na.rm=TRUE) }

A = pollutantmean(“C:/Users/MH026898/OneDrive - Cerner Corporation/Workspaces/courses-master/02_RProgramming/specdata”,“sulfate”,c(“001”,“002”,“003”))

A = 4.278766

Funciones útiles

file.path(“folder1”,“folder2”,“file1.csv”) –> Permite acceder al fichero independientemente del sistema operativo, en el caso de linux te devuelve “folder1/folder2/file1.csv”

generar4 números aleatorios del 1 al 10

v <- sample(10,4)

wich(v > 7) nos da los indices de los elementos que su valor sea mayor que 7

any(v>7 ) devuelve true si encuntra alguno mayor que 7

all(v>7) devuelve true si todos son mayor que 7

generar 30 números aleatorios entre 5 y 10

seq(5, 10, length=30)

generar una secuencia entre 1 y 10 seq(1,10)

generar secuencia con intervalos de 0,5 (el doble de valores)

seq(1,10,by=0.5)

Repetir un valor n veces rep(0, times = 40)

repetir tres valores n veces rep(c(0,1, 2), times = 10)

seq_along(x) -> nos da un vector de igual longitud que X y relleno con una secuencia de 1 a length(x)

range(x) -> devuelve el máximo y el mínimo valor de lo que se le pase

split(airquality,airquality$mounth) –> devuelve una lista de dataframes, cada dataframe correspodiente al mes del dataset inicial.

qownnotes-media-b14140

qownnotes-media-b14140

Generar números aleatorios según una distribuciòn

qownnotes-media-e13884

qownnotes-media-e13884

qownnotes-media-v13884

qownnotes-media-v13884

qownnotes-media-n13884

qownnotes-media-n13884

Hay que tener en cuenta que si no se cambia el seed, nos van a salir los mismos número aleatorios una y otra vez, como en este caso, al volver a poner el seed = 1 nos salen los mismos número que en la primera vez. Esto es útil si queremos reproducir un resultado, bastará con poner el mismo seed.

qownnotes-media-Y13884

qownnotes-media-Y13884

En este ejemplo generamos aleatoriamente valores con una distribución de poisson, además también calculamos la distribución acumnulada en un punto, esto es la probabilidad de que x sea igual o menor a ese valor

qownnotes-media-c13884

qownnotes-media-c13884

Hasta aquí lo que tenemos es la creación de valores discretos que siguen una distribución. Si queremos que sean datos lineales de manera que a un valor de x le corresponda un valor de y, tendremos que hacerlo de la siguiente manera:

Para el caso de el valor de las x tenga distribución normal:

qownnotes-media-M13884

qownnotes-media-M13884

qownnotes-media-n13884

qownnotes-media-n13884

Para el caso de que el valor de las x tenga distribución binomial, por ejemplo “género”

qownnotes-media-i13884

qownnotes-media-i13884

La variable x es binomial y sin embargo la variable y sigue siendo normal.

qownnotes-media-v13884

qownnotes-media-v13884

Si los valores de x son continuos y obedecen a una distribución de poisson:

qownnotes-media-b13884

qownnotes-media-b13884

qownnotes-media-p13884

qownnotes-media-p13884

Estructuras de control

qownnotes-media-Jl1868

qownnotes-media-Jl1868

qownnotes-media-fT1868

qownnotes-media-fT1868

qownnotes-media-Ne1868

qownnotes-media-Ne1868

qownnotes-media-Xg1868

qownnotes-media-Xg1868

qownnotes-media-dd1868

qownnotes-media-dd1868

qownnotes-media-sE1868

qownnotes-media-sE1868

Funciones

Devuelven lo último que se opera.

qownnotes-media-Hk5552

qownnotes-media-Hk5552

Podemos incluir parámetros para que no procese nulos, por ejemplo en la función que hemos creado para que calcule la media de todas las columnas de un dataset o matrix.

qownnotes-media-Tc5552

qownnotes-media-Tc5552

qownnotes-media-Sh5552

qownnotes-media-Sh5552

qownnotes-media-aK5552

qownnotes-media-aK5552

SI una función que queremos usar dentro de nuestra función tiene muchos parámetros y sólo queremos mapearlos de unos a otros se puede hacer con …

qownnotes-media-Qd5552

qownnotes-media-Qd5552

qownnotes-media-Up5552

qownnotes-media-Up5552

qownnotes-media-qV5552

qownnotes-media-qV5552

Ejemplos:

Crear una función que calcule la media

my_mean <- function(my_vector) { # Write your code here! # Remember: the last expression evaluatwill be returned! sum(my_vector)/length(my_vector)

Función que calcula el resto en una división, y le ponemos un parámetro por defecto porque lo usamos mucho

remainder <- function(num, divisor=2) { evaluated will be returned! num%%divisor }

Usar función como parámetro

evaluate <- function(func, dat){

func(dat) }

Usar los puntos suspensivos para parámetros variables, función que añade start y stop a cualquier combinación de palabras que haya en medio

telegram <- function(…){ c <- paste(…,“STOP”) paste(“START”,c) }

coger ciertos parámetos por nombre dentro de los parámetros variables

mad_libs <- function(…){

args <- list(…) place <- args[[“place”]] adjective <- args[[“adjective”]] noun <- args[[“noun”]] paste(“News from”, place, “today where”, adjective, “students took to the streets in protest of the new”, noun, “being installed on campus.”) }

Crear un operador binario tipo +, que opere con lo que tenga a un lado y al otro, por ejemplo

“Hola” %p% “mundo” %p% “libre”

“%p%” <- function(left,right){ paste(left,right)

}

Ejercicios de creación de funciones:

qownnotes-media-Y12748

qownnotes-media-Y12748

qownnotes-media-R12748

qownnotes-media-R12748

qownnotes-media-a12748

qownnotes-media-a12748

qownnotes-media-U12748

qownnotes-media-U12748

qownnotes-media-I12748

qownnotes-media-I12748

qownnotes-media-x12748

qownnotes-media-x12748

Fechas

FECHAS

Las fechas en R tienen dos posibles objetos que los contengan

d1 <- as.Date(“1969-01-01”)

posixlt (el objeto contiene información adicional como segundos, dia de la semana, mes, etc)

qownnotes-media-Bq7224

qownnotes-media-Bq7224

posixct sólo te da el número de segundos

qownnotes-media-Oq7224

qownnotes-media-Oq7224

t2 <- as.POSIXlt(Sys.time())

qownnotes-media-qx7408

qownnotes-media-qx7408

qownnotes-media-hw7408

qownnotes-media-hw7408

Para sacarlo de fechas Posixct existen las funciones weekdays(), month(),etc…

difftime(Sys.time(), t1, units = ‘days’) porque por defecto nos lo devuelve en minutos

qownnotes-media-AN7224

qownnotes-media-AN7224

Si queremos ver el contenido interno de la variable sin pasar por la clase, hacemos unclass()

Por ejemplo una variable fecha, si la visualizo, al ser tipo fecha me la muesta con su formato, y si hacemos unclass(fecha) nos devolverá el número de días que han pasado desde 1-1-1970 que es como internamente se representa

Bucles, lapply,mapply,sapply

BUCLES lapply siempre devuelve una lista, lo cual hay veces que no es lo más práctico ni eficiente.

qownnotes-media-qI2776

qownnotes-media-qI2776

qownnotes-media-Ca2776

qownnotes-media-Ca2776

sapply sirve para que si todos los elementos que devuelve lapply son del mismo tipo, devolver un vector, así ganar practicidad y eficiencia

qownnotes-media-Vz2776

qownnotes-media-Vz2776

qownnotes-media-R14824

qownnotes-media-R14824

Apply por si queremos iterar sólo por las filas o sólo por las columnas de un dataframe o matrix

qownnotes-media-xr2776

qownnotes-media-xr2776

qownnotes-media-ue2776

qownnotes-media-ue2776

qownnotes-media-Vx2776

qownnotes-media-Vx2776

En el primer ejemplo se coge la segunda dimensión, en el siguiente se toma la primera dimension

qownnotes-media-IG2776

qownnotes-media-IG2776

qownnotes-media-PA2776

qownnotes-media-PA2776

qownnotes-media-zr2776

qownnotes-media-zr2776

qownnotes-media-ME2776

qownnotes-media-ME2776

qownnotes-media-HS2776

qownnotes-media-HS2776

qownnotes-media-C14824

qownnotes-media-C14824

qownnotes-media-af2776

qownnotes-media-af2776

qownnotes-media-Fm2776

qownnotes-media-Fm2776

qownnotes-media-Y12084

qownnotes-media-Y12084

qownnotes-media-R12084

qownnotes-media-R12084

Funciones útiles y trucos

FUNCION STR

Junto con summary obtenemos un resumen del contenido de los datos, sin embargo con str obtenemos toda la información sobre el continente de los datos

qownnotes-media-t14140

qownnotes-media-t14140

OPTIMIZACIÓN CÓDIGO

TRUCOS PARA LEER TABLAS GRANDES

read.table o read.csv:

poner comment.char = " " si no hay comentarios en el archivo.

Poner el tipo de las columnas antes para que no lo autocalcule, si se sabe a priori simplemente se añade, si no se puede hacer algo así:

qownnotes-media-e14076

qownnotes-media-e14076

Si nos peta la memoria podemos hacer un cálculo rápido de esta manera

qownnotes-media-F14076

qownnotes-media-F14076

Se pueden pasar a disco y recuperar los objetos en memoria con dput y dget

qownnotes-media-g14076

qownnotes-media-g14076

qownnotes-media-l14956

qownnotes-media-l14956

qownnotes-media-g14956

qownnotes-media-g14956

Ejemplo, con lm se hacen distintas llamadas internas a otras funciones, para saber cuánto tardan cada una:

qownnotes-media-O14956

qownnotes-media-O14956

qownnotes-media-H14956

qownnotes-media-H14956

qownnotes-media-E14956

qownnotes-media-E14956

qownnotes-media-G14956

qownnotes-media-G14956

qownnotes-media-o14956

qownnotes-media-o14956

qownnotes-media-K14956

qownnotes-media-K14956

qownnotes-media-a14956

qownnotes-media-a14956

qownnotes-media-h14956

qownnotes-media-h14956

qownnotes-media-O14956

qownnotes-media-O14956

qownnotes-media-J14956

qownnotes-media-J14956

qownnotes-media-l14956

qownnotes-media-l14956

SAMPLING

qownnotes-media-X14956

qownnotes-media-X14956

qownnotes-media-k14956

qownnotes-media-k14956

qownnotes-media-x14956

qownnotes-media-x14956

qownnotes-media-Y14956

qownnotes-media-Y14956

qownnotes-media-Y14956

qownnotes-media-Y14956

qownnotes-media-f14956

qownnotes-media-f14956

qownnotes-media-c14956

qownnotes-media-c14956

qownnotes-media-C14956

qownnotes-media-C14956

qownnotes-media-E14956

qownnotes-media-E14956

qownnotes-media-X14956

qownnotes-media-X14956

GRÁFICAS BÁSICAS

qownnotes-media-q14956

qownnotes-media-q14956

qownnotes-media-o14956

qownnotes-media-o14956

qownnotes-media-S14956

qownnotes-media-S14956

qownnotes-media-h14956

qownnotes-media-h14956

Cambiar filas por columnas en un dataframe

Country.Name 1997 1998 1999 2000 1 Country1 1 1 1 1 2 Country2 2 4 7 10 3 Country3 4 2 1 5

df <- structure(list(Country.Name = c("Country1", "Country2", "Country3"
), `1997` = c(1L, 2L, 4L), `1998` = c(1L, 4L, 2L), `1999` = c(1L,
7L, 1L), `2000` = c(1L, 10L, 5L)), .Names = c("Country.Name",
"1997", "1998", "1999", "2000"), class = "data.frame", row.names = c(NA,
-3L))

df2 <- data.frame(t(df[-1]))
colnames(df2) <- df[, 1]

df2
##      Country1 Country2 Country3
## 1997        1        2        4
## 1998        1        4        2
## 1999        1        7        1
## 2000        1       10        5

Miguel Angel Huerta

16 de octubre de 2018